
#include "EggNinePCH.h"

#include "presentTechnique.h"
#include "simpleShader.h"

namespace EggNine {


PresentTechnique::PresentTechnique(const string& shaderName)
    :   IProgram(shaderName, "Present")
{
    char log[5000];
    int effect;
    effect=glfxGenEffect();
    glfxParseEffectFromFile(effect, GRAPHICS_PATH("shaders/simpleShader.glsl"));
    m_programId=glfxCompileProgram(effect, "SimpleShader");
    glfxGetEffectLog(effect, log, sizeof(log)-1);
    cerr<<log<<endl;

    m_attribMap["Position"]=POSITION_SIMPLE;
    m_attribMap["Normal"]=NORMAL_SIMPLE;
    m_attribMap["TexCoord"]=TEXCOORDS_SIMPLE;

    TexUnit tUnit;
    tUnit.m_location=glGetUniformLocation(m_programId, "TexDiffuse");
    tUnit.m_unit=0;
    tUnit.m_target=GL_TEXTURE_2D;
    tUnit.m_sampler=glfxGenerateSampler(effect, "TexDiffuse");
    m_texUnits["Diffuse"]=tUnit;

    glfxDeleteEffect(effect);
}

PresentTechnique::PresentTechnique(const string& name, const string& alias)
    :   IProgram(name, alias)
{
}

PresentTechnique::~PresentTechnique()
{
}

void PresentTechnique::DrawPass(int pass/* =0 */) const
{
}

void PresentTechnique::SetDiffuseTexture(GLuint tex) const
{
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
}

void PresentTechnique::GetActiveUniforms(const UniformMap& uBlocks)
{
    m_uBlocks.push_back(uBlocks.at("Lights"));
    m_uBlocks.push_back(uBlocks.at("Matrices"));
    m_uBlocks.push_back(uBlocks.at("Model"));
}

void PresentTechnique::SetViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
    m_viewportX=x;
    m_viewportY=y;
    m_viewportWidth=width;
    m_viewportHeight=height;
}

void PresentTechnique::ResetStateToProgram() const
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glDepthFunc(GL_LEQUAL);
    glViewport(m_viewportX, m_viewportY, m_viewportWidth, m_viewportHeight);
    glUseProgram(m_programId);
}



DisplacedQuadTechnique::DisplacedQuadTechnique(const string& shaderName)
    :   PresentTechnique(shaderName, "DisplacedQuad")
{
    char log[5000];
    int effect;
    effect=glfxGenEffect();
    glfxParseEffectFromFile(effect, GRAPHICS_PATH("shaders/tessQuadfx.glsl"));
    m_programId=glfxCompileProgram(effect, "DisplacedQuad");
    glfxGetEffectLog(effect, log, sizeof(log)-1);
    fprintf(stderr, log);

    m_attribMap["Position"]=glGetAttribLocation(m_programId, "VSIn.Position");
    m_attribMap["TexCoord"]=glGetAttribLocation(m_programId, "VSIn.TexCoords");

    TexUnit tUnit;
    tUnit.m_location=glGetUniformLocation(m_programId, "TexDisp");
    tUnit.m_unit=1;
    tUnit.m_target=GL_TEXTURE_2D;
    tUnit.m_sampler=glfxGenerateSampler(effect, "TexDisp");
    m_texUnits["Displacement"]=tUnit;

    tUnit.m_location=glGetUniformLocation(m_programId, "TexDiffuse");
    tUnit.m_unit=0;
    tUnit.m_target=GL_TEXTURE_2D;
    tUnit.m_sampler=glfxGenerateSampler(effect, "TexDiffuse");
    m_texUnits["Image"]=tUnit;

    glfxDeleteEffect(effect);
}

DisplacedQuadTechnique::~DisplacedQuadTechnique()
{}

void DisplacedQuadTechnique::GetActiveUniforms(const UniformMap& uBlocks)
{
    PresentTechnique::GetActiveUniforms(uBlocks);
    m_uBlocks.push_back(uBlocks.at("MaterialAttrs"));
}

void DisplacedQuadTechnique::SetDispTexture(GLuint tex) const
{
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, tex);
}


} // EggNine